/*
 * To change this license header, choose License Headers in Project Properties.
 * To change this template file, choose Tools | Templates
 * and open the template in the editor.
 */
package com.ambimmort.ucagent.modules.server;

import com.ambimmort.ucagent.modules.server.plugins.WhitelistFilter;
import java.io.IOException;
import java.net.InetSocketAddress;
import java.sql.SQLException;
import java.util.logging.Level;
import java.util.logging.Logger;

import net.sf.json.JSONObject;

import org.apache.mina.core.service.IoAcceptor;
import org.apache.mina.filter.codec.ProtocolCodecFilter;
import org.apache.mina.filter.firewall.ConnectionThrottleFilter;
import org.apache.mina.filter.logging.LoggingFilter;
import org.apache.mina.transport.socket.nio.NioSocketAcceptor;

import com.ambimmort.ucagent.appframework.Module;
import com.ambimmort.ucagent.database.SystemPropertyUtil;
import com.ambimmort.ucagent.modules.server.codec.UcProtocolCodecFactory;
import com.ambimmort.ucagent.modules.server.dpi.DPIEndPoint;
import com.ambimmort.ucagent.modules.server.dpi.DPIEndPointManager;

/**
 *
 * @author 定巍
 */
public class ServerModule extends Module {

    private NioSocketAcceptor acceptor = null;
    private WhitelistFilter whiteListFilter = new WhitelistFilter();

    private JSONObject state = new JSONObject();

    public ServerModule() {
        acceptor = new NioSocketAcceptor();
//        acceptor.getFilterChain().addLast("logger", new LoggingFilter());
        acceptor.setReuseAddress(true);
        acceptor.getFilterChain().addLast("whiteList", whiteListFilter);
        acceptor.getFilterChain().addLast("codec", new ProtocolCodecFilter(new UcProtocolCodecFactory()));
        acceptor.setHandler(new UcAgentServerHandler());
    }

    public WhitelistFilter getWhiteListFilter() {
        return whiteListFilter;
    }

    public void bind() {
        try {
            acceptor.bind(new InetSocketAddress(Integer.parseInt(SystemPropertyUtil.getInstance().getProperty("server.port"))));

        } catch (IOException ex) {
            Logger.getLogger(ServerModule.class.getName()).log(Level.SEVERE, null, ex);
            System.out.println("%%%%%%%%%%");
            System.exit(-1);
        }
    }

    public void bind(int port) {
        try {
            acceptor.bind(new InetSocketAddress(port));
        } catch (IOException ex) {
            Logger.getLogger(ServerModule.class.getName()).log(Level.SEVERE, null, ex);
            System.out.println("%%%%%%%%%%");
            System.exit(-1);
        }
    }

    public void unbind() {
        acceptor.unbind();
    }

    @Override
    public String getName() {
        return "ZFServerComponent";
    }

    @Override
    public JSONObject getStates() {
        return state;
    }

    @Override
    protected void refreshState() {
    }

    @Override
    protected void poststart() throws Throwable {
        DPIEndPointManager.getInstance().refresh();
        System.out.println("==>Loaded active DPIs:");
        for (DPIEndPoint ep : DPIEndPointManager.getInstance().getEndPoints().values()) {
            System.out.println("=>" + ep.getDpiEndPointBean().getName() + "[" + ep.getDpiEndPointBean().getMasterIp() + "] CC:" + ep.getDpiEndPointBean().isIsClientChannelConnected() + " SC:" + ep.getDpiEndPointBean().isIsServerChannelConnected());
        }
    }

    @Override
    protected void prestart() throws Throwable {
        bind();
    }

}
